<?php

namespace App\Http\Controllers\Mileage;

use App\Http\Controllers\Controller;
use App\Imports\Mileage\MileageImport;
use App\Models\Bus\BusDistribution;
use App\Models\Mileage\Mileage;
use App\Models\Mileage\MileageRefreshLog;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
use Maatwebsite\Excel\Facades\Excel;

class MileageController extends Controller
{
    public function mileageList(Request $request)
    {
        $params = $countParams = $request->all();
        unset($countParams['pageNumber'], $countParams['pageSize']);
        $data = $this->getMileageList($params)->orderByDesc('date')->orderBy('line')->get()->toArray();
        if ($data) {
            $data = $this->transData($data);
        }
        $dataCount = $this->getMileageList($countParams)->count();

        return response()->formatJson(['gasRecord' => $data, 'count' => $dataCount]);
    }

    public function getMileageList($params)
    {
        $query = Mileage::query();

        if (isset($params['license_plate_num'])) {
            $query->where('license_plate_num', 'like', '%'.$params['license_plate_num'].'%');
        }

        if (isset($params['line']) && '-1' !== $params['line']) {
            $query->where('line', $params['line']);
        }

        if ($params['date'][0] !== null && $params['date'][1] !== null) {
            $startDate = date('Y-m-d', strtotime($params['date'][0]));
            $endDate = date('Y-m-d', strtotime($params['date'][1]));
            $query->whereBetween('date', [$startDate, $endDate]);
        }

        if (isset($params['pageNumber'], $params['pageSize'])) {
            $query
                ->limit($params['pageSize'])
                ->offset(($params['pageNumber'] - 1) * $params['pageSize']);
        }

        return $query;
    }

    public function transData($data)
    {
        foreach ($data as $key => $bus) {
            foreach ($bus as $value) {
                $data[$key]['edit'] = false;
            }
        }

        return $data;
    }

    /**
     * 导入加气记录
     *
     * @param  Request  $request
     *
     * @return mixed
     */
    public function importMileage(Request $request)
    {
        $dbDate = Mileage::query()->get(['date'])->toArray();
        $uniqueDate = [];
        if ($dbDate) {
            $uniqueDate = array_unique(array_column($dbDate, 'date'));
        }
        $urlParse = parse_url($request->input('url'));
        $excelData = Excel::toArray(new MileageImport, public_path().$urlParse['path']);
        $fullData = $excelData[0];

        // 结算日期
        $date = substr(trim($fullData[0][0]), -10);
        if ($uniqueDate && in_array($date, $uniqueDate, true)) {
            return response()->formatJson(false, $date.'数据已存在，导入终止！');
        }

        // 删除前两行
        array_shift($fullData);
        array_shift($fullData);

        $data = [];
        $fields = [
            'unit',
            'line',
            'license_plate_num',
            'self_numbering',
            'plan_times',
            'actual_times',
            'departure_rate',
            'operating_mileage',
            'non-operating_mileage',
            'gps_mileage',
            'plan_mileage',
            'rated_mileage',
        ];
        $unsetKeys = [];
        // 整理数据，填充合并的单元格数据
        foreach ($fullData as $k => $row) {
            if (! array_filter($row)) {
                $unsetKeys[] = $k;
                continue;
            }
            if ($row[0] === null) {
                $fullData[$k][0] = $fullData[$k - 1][0];
            }
            if ($row[1] === null) {
                $fullData[$k][1] = $fullData[$k - 1][1];
            }
            if ($row[1] === '合计') {
                $unsetKeys[] = $k;
            }
            if ($row[0] === '总计') {
                $unsetKeys[] = $k;
            }
            if ($row[2] === '小计') {
                $unsetKeys[] = $k;
            }
        }
        // 删除空数据
        if ($unsetKeys) {
            foreach ($unsetKeys as $v) {
                unset($fullData[$v]);
            }
        }
        // 整理数据，填充合并的单元格数据
        foreach ($fullData as $k => $row) {
            $item = [];
            foreach ($fields as $index => $field) {
                $item[$field] = $row[$index];
            }
            if ($item['license_plate_num']) {
                $item['license_plate_num'] = Str::of($item['license_plate_num'])->replace('陕G', '');
            }
            if ($item['departure_rate']) {
                $item['departure_rate'] = str_replace('%', '', $item['departure_rate']) / 100;
            }
            $item['operating_mileage'] = (float) str_replace(',', '', $item['operating_mileage']);
            $item['non-operating_mileage'] = (float) str_replace(',', '', $item['non-operating_mileage']);
            $item['gps_mileage'] = (float) str_replace(',', '', $item['gps_mileage']);
            $item['plan_mileage'] = (float) str_replace(',', '', $item['plan_mileage']);
            $item['rated_mileage'] = (float) str_replace(',', '', $item['rated_mileage']);
            $item['date'] = $date;
            unset($item['unit']);
            $item['created_at'] = date('Y-m-d H:i:s');
            $data[] = $item;
        }

        return response()->formatJson(Mileage::query()->insert($data), '导入成功');
    }

    /**
     * 刷新里程数据
     *
     * @param  Request  $request
     *
     * @return void
     */
    public function refreshMileageData(Request $request)
    {
        $params = $request->all();

        if (isset($params['date']) && $params['date'][0] !== null && $params['date'][1] !== null) {
            $startDay = date('Y-m-d', strtotime($params['date'][0]));
            $lastDay = date('Y-m-d', strtotime($params['date'][1]));
        } else {
            return response()->formatJson(['result' => '', 'status' => '失败'], '请选择日期范围！');
        }
        $insertData['startDay'] = $startDay;
        $insertData['lastDay'] = $lastDay;
        $insertData['operator'] = Auth::user()->name;
        $msg = '';
        DB::beginTransaction();
        try {
            if ($startDay && $lastDay) {
                $dates = getListFromDateRange($startDay, $lastDay);
                // 同步数据
                foreach ($dates as $date) {
                    $updateResult = $this->updateOrInsertSignData($date);
                    sleep(12);
                }
            } else {
                $date = $startDay ?: $lastDay;
                $updateResult = $this->updateOrInsertSignData($date);
            }
            if ($updateResult) {
                $insertData['status'] = '成功';
                $msg = '恭喜您，刷新里程数据成功！';
                DB::commit();
            }
        } catch (\Throwable $th) {
            DB::rollBack();
            $insertData['status'] = '失败';
            $msg = '很遗憾，刷新里程数据失败，请重试！'.$th->getMessage();
        }
        //写入操作记录
        $mileageRefreshLog = new MileageRefreshLog($insertData);
        $result = $mileageRefreshLog->save();
        return response()->formatJson(['result' => $result, 'status' => $insertData['status']], $msg);
    }

    /**
     * 获取刷新里程数据的操作记录
     *
     * @param  Request  $request
     *
     * @return void
     */
    public function mileageLogList(Request $request)
    {
        $params = $countParams = $request->all();
        unset($countParams['pageNumber'], $countParams['pageSize']);
        $result = $this->getMileageLogQuery($params)->get()->toArray();
        $dataCount = $this->getMileageLogQuery($countParams)->count();
        return response()->formatJson(['result' => $result, 'count' => $dataCount]);

    }

    public function getMileageLogQuery($params)
    {
        $query = MileageRefreshLog::query();
        if (isset($params['operator']) && ! empty($params['operator'])) {
            $query->where('operator', 'like', '%'.$params['operator'].'%');
        }
        if (isset($params['date']) && $params['date'][0] !== null && $params['date'][1] !== null) {
            $startDate = date('Y-m-d', strtotime($params['date'][0]));
            $endDate = date('Y-m-d', strtotime($params['date'][1]));
            $query->whereBetween('created_at', [$startDate, $endDate]);
        }
        if (isset($params['pageNumber'], $params['pageSize'])) {
            $query->limit($params['pageSize'])
                ->offset(($params['pageNumber'] - 1) * $params['pageSize']);
        }
        return $query->orderByDesc('created_at');
    }

    public function updateOrInsertSignData($date)
    {
        $lines = BusDistribution::query()->where('line', '!=', '0')->groupBy('line')->pluck('line')->toArray();

        $sign = Http::get('http://117.34.118.31:8101/api/bus/mileage/list', [
            'date' => $date,
        ]);
        $data = $sign->json();
        $code = $data['code'];
        if ($code === 200) {
            $insertData = [];
            foreach ($data['data'] as $v) {
                if (in_array((int) $v['lineName'], $lines, true) && (string) $v['orgName'] === '安康公共交通有限责任公司') {
                    $insertData[] = [
                        'date'                  => $date,
                        'line'                  => $v['lineName'],
                        'license_plate_num'     => str_replace('陕G', '', $v['busNum']),
                        'self_numbering'        => $v['busCode'],
                        'plan_times'            => $v['planTrip'],
                        'actual_times'          => $v['runTrip'],
                        'departure_rate'        => $v['rate'],
                        'operating_mileage'     => $v['runMileage'],
                        'non-operating_mileage' => $v['nonMileage'],
                        'gps_mileage'           => $v['totalMileage'],
                        'plan_mileage'          => $v['planMileage'],
                        'rated_mileage'         => $v['ratedMileage'],
                        'created_at'            => date('Y-m-d H:i:s'),
                    ];
                }
            }
            // 先删除数据，再插入
            DB::table('akbus_mileage')->where('date', $date)->delete();
            $result = DB::table('akbus_mileage')->insert($insertData);
        } else {
            $result = false;
        }
        return $result;
    }
}
